Skip to content

Fix canonical routed preview origins#2098

Merged
chubes4 merged 4 commits into
mainfrom
fix-2092-canonical-preview-origin
Jul 26, 2026
Merged

Fix canonical routed preview origins#2098
chubes4 merged 4 commits into
mainfrom
fix-2092-canonical-preview-origin

Conversation

@chubes4

@chubes4 chubes4 commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • expose declared runtime.preview.siteUrl route aliases as the browser-visible origin while proxying transport to the disposable local preview
  • apply the canonical topology consistently across probes, actions, scenarios, and editor runners
  • distinguish canonical browser, local proxy, and upstream runtime origins in browser artifacts

Architecture and root cause

route-host previously rewrote individual requests with Playwright interception after navigation had already resolved against the ephemeral 127.0.0.1:<port> preview. That made network requests work but left the document at the wrong origin, so browser-native History, storage, cookie, form, and redirect semantics diverged from production.

For a declared HTTP runtime.preview.siteUrl alias, local Playground runners now create the browser context with the local preview server as an HTTP proxy and navigate against the canonical site URL. The browser therefore owns canonical same-origin semantics while the proxy forwards the request to the disposable upstream runtime. Proxy absolute-form requests retain their canonical Host, and local-upstream redirects are translated back to the browser-visible host.

Security boundary

  • only a siteUrl hostname explicitly present in route-host activates canonical origin preservation
  • canonical proxy mode blocks every undeclared host before transport, including top-level navigation and redirect escapes
  • explicit block-host still wins over routed aliases
  • providers that cannot preserve the declared protocol return preview-canonical-origin-preservation-inconclusive instead of navigating under a different origin

Compatibility

The existing request-interception route remains unchanged for non-canonical routed previews. Public and secure preview modes retain their existing effective origins. The local Playground provider currently preserves declared HTTP aliases; HTTPS canonical aliases are reported as structured inconclusive because the local proxy does not terminate canonical TLS.

Tests

  • npm run test:browser-canonical-preview-origin
  • npm run test:browser-callback-materialization-contracts
  • npx tsx tests/browser-adaptive-exploration.test.ts (16 passed)
  • npm run build
  • git diff --check
  • npm run check reached the existing smoke suite, then failed at unrelated command-registry-smoke: wordpress.collect-workload-result outputShape should mention outputSchema id

Fixes #2092

@chubes4
chubes4 force-pushed the fix-2092-canonical-preview-origin branch from af8d250 to fc41d30 Compare July 26, 2026 17:14
@chubes4

chubes4 commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed all requested changes and rebased non-interactively onto current origin/main.

Updates:

  • enforce preview readiness before context creation/navigation in browser actions, multi-actor scenarios, editor open/actions/validate, while retaining structured inconclusive diagnostics in artifacts
  • strip client Forwarded and X-Forwarded-* headers; derive canonical host/port/protocol from the authoritative proxy request target for upstream forwarding and redirect rewriting
  • use HTTP undeclared-host escape coverage and assert structured policy-block evidence
  • inject spoofed forwarding headers and verify canonical upstream values
  • include test:browser-canonical-preview-origin in test:generic-primitives / required check coverage

Commits:

  • ef291ef8 fix: preserve canonical routed preview origins
  • fc41d305 fix: enforce canonical preview boundaries

Checks:

  • npm run build passed
  • npm run test:browser-canonical-preview-origin passed
  • npm run test:browser-callback-materialization-contracts passed
  • npm run test:generic-primitives passed, including canonical origin integration coverage
  • npx tsx tests/browser-adaptive-exploration.test.ts passed: 21/21
  • git diff --check passed
  • npm run check passed production-boundary enforcement, build, and generic primitives, then stopped at the existing main-branch command-registry-smoke failure tracked by command-registry-smoke fails on main: wordpress.collect-workload-result outputShape missing outputSchema id mention #1745: wordpress.collect-workload-result outputShape should mention outputSchema id

@chubes4

chubes4 commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator Author

Required PR CI coverage is now wired at head 31766ee2 (test: gate canonical preview origins in PR CI).

  • Agent Task Contracts directly runs npm run test:browser-canonical-preview-origin
  • pull/push path filters include the canonical regression test and all topology/proxy/runner/artifact files that can affect the contract
  • pinned actionlint 1.7.7 passed both .github/workflows/agent-task-contracts.yml and .github/workflows/run-agent-task.yml
  • npm run test:agent-task-contracts passed
  • npm run test:browser-canonical-preview-origin passed
  • npm run test:browser-callback-materialization-contracts passed
  • git diff --check passed

@chubes4

chubes4 commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator Author

Green head: c0691e99 (ci: install Chromium for browser contracts).

The required Agent Task Contracts workflow now:

  • caches only ~/.cache/ms-playwright under a lockfile-keyed Chromium cache key
  • runs npx playwright install --with-deps chromium, avoiding Firefox/WebKit downloads
  • executes the canonical browser regression test afterward

Verification:

  • pinned actionlint 1.7.7 passed both workflows locally
  • canonical browser and Agent Task contract suites passed locally
  • both GitHub workflow-lint jobs passed
  • both GitHub contracts jobs passed
  • GitHub step Run npm run test:browser-canonical-preview-origin concluded success

@chubes4
chubes4 merged commit ab8f91c into main Jul 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Routed previews break same-origin History API calls using canonical WordPress URLs

1 participant